/*
 * CameraMicro.h
 *
 *  Created on: 2012-05-27
 *      Author: mathieu
 */

#ifndef CAMERAMICRO_H_
#define CAMERAMICRO_H_

#include "semol/core/SensorimotorEvent.h"

#include <utilite/UThreadNode.h>
#include <utilite/UEventsManager.h>
#include <utilite/UImageCapture.h>
#include <utilite/UAudioCaptureFFT.h>

namespace semol
{

class CameraMicro : public UThread
{
public:
	CameraMicro(UAbstractImageCapture * camera, UAudioCaptureFFT * micro) :
		camera_(camera),
		micro_(micro)
	{
	}

protected:
	void mainLoopBegin()
	{
		if(!camera_ || !micro_ )
		{
			UERROR("Camera and/or Micro are null");
			this->kill();
			return;
		}
		micro_->startRecorder();
	}

	void mainLoop()
	{
		std::vector<std::vector<float> > frameFreq;
		// frame rate should depend on micro and camera frame rate
		// (getFrame() and takeImage() are blocking calls)
		std::vector<std::vector<char> > frame = micro_->getFrame(frameFreq, true);
		if(frame.empty())
		{
			if(this->isRunning())
			{
				UEventsManager::post(new UAudioEvent(UAudioEvent::kTypeNoMoreFrames));
				this->kill();
			}
			return;
		}
		cv::Mat image = camera_->takeImage();
		if(image.empty())
		{
			UEventsManager::post(new UImageEvent(UImageEvent::kCodeNoMoreImages));
			this->kill();
			return;
		}
		std::list<SensorRaw> sensors;
		sensors.push_back(SensorRaw(Sensor::kTypeImage, image));
		sensors.push_back(SensorRaw(Sensor::kTypeAudioFreqSqrdMagn, Sensor::fromAudio(frameFreq)));
		UEventsManager::post(new SensorimotorEvent(sensors, std::list<Actuator>()));
	}

	void mainLoopKill()
	{
		if(micro_)
		{
			micro_->stop();
		}
	}

private:
	UAbstractImageCapture * camera_;
	UAudioCaptureFFT * micro_;
};

}

#endif /* CAMERAMICRO_H_ */
